<script lang="tsx" setup>
import { computed, defineExpose, inject, ref, watch } from 'vue';
import { useAntdForm, useFormRules } from '@/hooks/common/form';
import { addMenu, updateMenu } from '@/service/api';
import { getAllPageRouteName } from '@/utils';
import { getLocalIcons } from '@/utils/icon';
import SvgIcon from '@/components/custom/svg-icon.vue';
import { getRoutePathByRouteName, getRoutePathWithParam, transformLayoutAndPageToComponent } from './shared';

export type OperateType = AntDesign.TableOperateType | 'addChild';

const close: any = inject('close');
const queryTableData: any = inject('query');

defineOptions({
  name: 'AddMenuForm'
});

interface Props {
  operateType: OperateType;
  menuList: any[];
  rowData: any;
}

const props = defineProps<Props>();

const { defaultRequiredRule, createRequiredRule } = useFormRules();

type RuleKey = Extract<keyof Model, 'parentId' | 'menuName' | 'orderNum' | 'status' | 'routeName'>;

const rules: Record<RuleKey, App.Global.FormRule> = {
  parentId: createRequiredRule('上级菜单不能为空'),
  menuName: createRequiredRule('菜单名称不能为空'),
  orderNum: createRequiredRule('显示顺不能为空'),
  status: defaultRequiredRule,
  routeName: createRequiredRule('路由名称不能为空')
};

interface Model {
  menuType: 'M' | 'C' | 'F' | 'A';
  menuName: string;
  parentId: any;
  iconType: any;
  icon: string | undefined;
  orderNum: number | undefined;
  layout: 'base' | 'blank' | undefined;
  routePath: any;
  routeName: any;
  page: any;
  status: '0' | '1';
  hideInMenu: string;
  perms: any;
  constant: string;
  href: string;
  queryList: any[];
  component: any;
  pathParam: any;
  query: string;
  visible: '0' | '1';
  isCache: '0' | '1';
  path: string;
  activeMenu: string;
}

const model = ref<Model>(createDefaultModel());
const { formRef, validate, resetFields } = useAntdForm();

const disabledMenuType = computed(() => props.operateType === 'edit');
function createDefaultModel(): Model {
  let modelObj: Model = {
    menuType: 'M',
    menuName: '',
    parentId: null,
    iconType: '2', // 默认使用本地图标
    icon: undefined,
    orderNum: undefined,
    layout: undefined,
    routePath: '',
    routeName: '',
    page: '',
    status: '0',
    hideInMenu: '1', // 默认不隐藏
    perms: '',
    constant: '1', // 默认非常量路由
    href: '',
    queryList: [],
    component: '',
    pathParam: '',
    query: '',
    visible: '1',
    isCache: '1', // 默认不缓存
    path: '',
    activeMenu: ''
  };
  const val = props.rowData;
  if (val) {
    if (props.operateType === 'edit') {
      // 深拷贝避免修改原始数据
      modelObj = JSON.parse(JSON.stringify(val));

      // 特殊处理system目录下的组件
      if (val.component && val.component.startsWith('view.system_')) {
        // 转换回system/格式
        const componentPath = val.component.replace('view.', '').split('_');
        if (componentPath.length >= 2) {
          modelObj.page = `${componentPath[0]}/${componentPath[1]}`;
        }
      } else if (val.component && val.component.startsWith('view.')) {
        // 处理其他组件，确保不带view.前缀
        modelObj.page = val.component.replace('view.', '');
      } else if (val.component) {
        // 其他情况也确保不带view.前缀
        modelObj.page = val.component.replace('view.', '');
      }

      // 转换数字类型字段
      modelObj.iconType = `${val.iconType || '2'}`;
      modelObj.constant = val.constant ? '0' : '1'; // 0表示是常量路由，1表示非常量路由
      modelObj.hideInMenu = val.hideInMenu ? '0' : '1'; // 0表示隐藏，1表示不隐藏
      // 修复路由路径处理逻辑
      if (val.path) {
        modelObj.routePath = val.path;
        // 特殊处理system目录下的路由
        if (val.component && val.component.startsWith('view.system_')) {
          const componentPath = val.component.replace('view.', '').split('_');
          if (componentPath.length >= 2) {
            // 修改为不带/system前缀的路径
            modelObj.routePath = `${componentPath[1]}/index`;
          }
        }
      } else {
        modelObj.routePath = '';
      }
      // 处理查询参数
      if (val.query) {
        try {
          const query = typeof val.query === 'string' ? JSON.parse(val.query) : val.query;
          modelObj.queryList = Object.keys(query).map(key => ({ key, value: query[key] }));
        } catch (e) {
          modelObj.queryList = [];
        }
      }
    }
    if (props.operateType === 'addChild') {
      modelObj.parentId = val.menuId || val.parentId;
      modelObj.menuType = 'M'; // 子菜单默认为目录类型
    }
  }
  return modelObj;
}

// createDefaultModel();

const layoutOptions: CommonType.Option[] = [
  {
    label: 'base',
    value: 'base'
  },
  {
    label: 'blank',
    value: 'blank'
  }
];

const menuIconTypeOptions = [
  {
    value: '1',
    label: 'iconify图标'
  },
  {
    value: '2',
    label: '本地图标'
  },
  {
    value: '3',
    label: '阿里字体图标'
  }
];

const enableStatusOptions: CommonType.Option[] = [
  {
    label: '正常',
    value: '0'
  },
  {
    label: '禁用',
    value: '1'
  }
];

const pageOptions = getAllPageRouteName().map(item => {
  return {
    label: item,
    value: item
  };
});

const menuTypeOptions = [
  {
    label: '目录',
    value: 'M'
  },
  {
    label: 'APP目录',
    value: 'A'
  },
  {
    label: '菜单',
    value: 'C'
  },
  {
    label: '按钮',
    value: 'F'
  }
];

const localIcons = getLocalIcons();
const localIconOptions = localIcons.map(item => ({
  label: () => (
    <div class="flex-y-center gap-16px">
      <SvgIcon localIcon={item} class="text-icon" />
      <span>{item}</span>
    </div>
  ),
  value: item
}));

const treeData = computed(() => {
  return [{ value: 0, label: '主类目', key: 0, children: props.menuList }];
});

const showLayout = computed(() => model.value.parentId === 0);
const showPage = computed(() => model.value.menuType == 'C');

// 动态获取路由地址
function handleUpdateRoutePathByRouteName() {
  if (model.value.routeName) {
    const routeName = model.value.routeName.split(':')[0];
    model.value.routePath = getRoutePathByRouteName(routeName);
  } else {
    model.value.routePath = '';
  }
}

function resetForm() {
  resetFields();
}

function addQuery(index: number) {
  model.value.queryList.splice(index + 1, 0, {
    key: '',
    value: ''
  });
}

function removeQuery(index: number) {
  model.value.queryList.splice(index, 1);
}
function getSubmitParams() {
  const { layout, page, pathParam, ...params } = model.value;
  console.log('model.value :>> ', model.value);
  if (layout !== null) {
    (params as any).layout = layout;
  }

  // 处理组件路径，特别是system目录下的组件
  let component = '';
  if (model.value.menuType === 'M') { // 目录类型
    component = layout ? `layout.${layout}` : '';
  } else if (model.value.menuType === 'C' && page) { // 菜单类型且有页面
    // 特殊处理system目录下的组件
    if (page.startsWith('system/')) {
      // 转换为 view.system_功能名_index 格式
      const pathParts = page.split('/');
      component = `${pathParts.slice(0, 2).join('_')}_index`;
    } else {
      component = page;
    }
  }
  (params as any).component = component;

  // 处理路由路径，确保格式正确且不出现双斜杠
  let routePath = model.value.routePath || '';
  // 如果是system目录下的路由，确保路径格式正确
  if (model.value.routeName && model.value.routeName.startsWith('system_')) {
    const parts = model.value.routeName.split('_');
    if (parts.length >= 2) {
      // 修改为不带/system前缀的路径
      routePath = `${parts[1]}/index`;
    }
  }

  // 确保路由路径不以双斜杠开始
  if (routePath.startsWith('//')) {
    routePath = routePath.substring(1);
  }

  routePath = getRoutePathWithParam(routePath, pathParam || '');
  const query: any = {};
  params.queryList
    .filter(item => item.key)
    .forEach(item => {
      query[item.key] = item.value;
    });
  (params as any).query = JSON.stringify(query);

  (params as any).routePath = routePath;
  model.value.path = routePath;
  (params as any).path = routePath;
  if (pathParam !== null) {
    (params as any).pathParam = pathParam;
  }
  (params as any).iconType = params.iconType?.replace('undefined', '');
  return params;
}
async function handleSubmit() {
  await validate();
  const params = getSubmitParams();
  console.log('params: ', params);
  let res;
  if (props.operateType === 'edit') {
    res = await updateMenu(params);
  } else {
    res = await addMenu(params);
  }

  const { error } = res;
  if (!error) {
    window.$message?.success('操作成功!');
    close();
    queryTableData();
  }
}

watch(
  () => model.value.routeName,
  (newVal, oldVal) => {
    // 只有当routePath为空或routeName和routePath有对应关系时才自动更新routePath
    if (model.value.routePath === '' ||
        (oldVal && getRoutePathByRouteName(oldVal.split(':')[0]) === model.value.routePath)) {
      handleUpdateRoutePathByRouteName();
    }
  }
);

// watch(
//   () => props.rowData,
//   val => {
//     console.log('val', val);
//     if (val) {
//       if (props.operateType === 'edit') {
//         model.value = val;
//         if (val.menuType === 'C') {
//           model.value.page = val.routeName.split(':')[0];
//         }
//         model.value.iconType = `${val.iconType}`;
//         model.value.constant = `${val.constant ? 0 : 1}`;
//         model.value.hideInMenu = `${val.hideInMenu ? 0 : 1}`;
//       }
//       if (props.operateType === 'addChild') {
//         console.log('val :>> ', val);
//         model.value.parentId = val.parentId;
//       }
//       if (val.query) {
//         const query = JSON.parse(val.query);
//         model.value.queryList = Object.keys(query).map(key => ({ key, value: query[key] }));
//       }
//     } else {
//       model.value = createDefaultModel();
//     }
//   },
//   {
//     immediate: true,
//     deep: true
//   }
// );

defineExpose({
  resetForm,
  handleSubmit
});
</script>

<template>
  <div class="my-form-content p-15px">
    <AForm ref="formRef" :model="model" :rules="rules" :label-col="{ lg: 8, xs: 4 }" label-wrap>
      <ARow :gutter="20">
        <ACol :lg="12" :xs="24">
          <AFormItem label="上级菜单" name="parentId">
            <ATreeSelect
              v-model:value="model.parentId"
              show-search
              style="width: 100%"
              :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
              placeholder="请选择上级菜单"
              allow-clear
              tree-default-expand-all
              :tree-data="treeData"
              tree-node-filter-prop="menuName"
            >
              <template #title="{ label }">
                {{ label }}
              </template>
            </ATreeSelect>
          </AFormItem>
        </ACol>
        <ACol :lg="12" :xs="24">
          <AFormItem label="菜单类型" name="menuType">
            <ARadioGroup v-model:value="model.menuType">
              <ARadio v-for="item in menuTypeOptions" :key="item.value" :value="item.value">
                {{ item.label }}
              </ARadio>
            </ARadioGroup>
          </AFormItem>
        </ACol>
        <ACol :lg="12" :xs="24">
          <AFormItem label="菜单名称" name="menuName">
            <AInput v-model:value="model.menuName" placeholder="请输入菜单名称" autocomplete="off" />
          </AFormItem>
        </ACol>
        <template v-if="model.menuType == 'M' || model.menuType == 'C'">
          <ACol :lg="12" :xs="24">
            <AFormItem label="路由名称" name="routeName">
              <AInput v-model:value="model.routeName" placeholder="请输入路由名称" autocomplete="off" />
            </AFormItem>
          </ACol>
          <ACol :lg="12" :xs="24">
            <AFormItem label="路由路径" name="routePath">
              <AInput v-model:value="model.routePath" placeholder="请输入路由路径" autocomplete="off" />
            </AFormItem>
          </ACol>
          <ACol v-if="showLayout" :lg="12" :xs="24">
            <AFormItem label="页面布局" name="layout">
              <ASelect v-model:value="model.layout" :options="layoutOptions" placeholder="请选择页面布局" />
            </AFormItem>
          </ACol>
          <ACol v-if="showPage" :lg="12" :xs="24">
            <AFormItem label="页面组件" name="page">
              <ASelect v-model:value="model.page" :options="pageOptions" placeholder="请选择页面组件" show-search />
            </AFormItem>
          </ACol>
          <ACol :lg="12" :xs="24">
            <AFormItem label="图标类型" name="iconType">
              <ASelect
                v-model:value="model.iconType"
                placeholder="青选择图标类型"
                @change="
                  () => {
                    model.icon = undefined;
                  }
                "
              >
                <ASelectOption v-for="item in menuIconTypeOptions" :key="item.value" :value="item.value">
                  {{ item.label }}
                </ASelectOption>
              </ASelect>
            </AFormItem>
          </ACol>

          <ACol :lg="12" :xs="24">
            <AFormItem label="图标" name="icon">
              <template v-if="model.iconType === '1'">
                <AInput v-model:value="model.icon" placeholder="请选择图标" class="flex-1" autocomplete="off">
                  <template #suffix>
                    <SvgIcon v-if="model.icon" :icon="model.icon" class="text-icon" />
                  </template>
                </AInput>
              </template>
              <template v-if="model.iconType === '2'">
                <ASelect v-model:value="model.icon" placeholder="请选择本地图标" :options="localIconOptions" />
              </template>
              <template v-if="model.iconType === '3'">
                <AInput v-model:value="model.icon" placeholder="请选择图标" class="flex-1" autocomplete="off">
                  <template #suffix>
                    <!-- <SvgIcon v-if="model.icon" :icon="model.icon" class="text-icon" /> -->
                    <span v-if="model.icon" :class="`icon iconfont ${model.icon}`"></span>
                  </template>
                </AInput>
              </template>
            </AFormItem>
          </ACol>

          <ACol :lg="12" :xs="24">
            <AFormItem :label="$t('page.manage.menu.keepAlive')" name="keepAlive">
              <ARadioGroup v-model:value="model.isCache">
                <ARadio value="0">是</ARadio>
                <ARadio value="1">否</ARadio>
              </ARadioGroup>
            </AFormItem>
          </ACol>
          <ACol :lg="12" :xs="24">
            <AFormItem label="隐藏菜单" name="visible">
              <ARadioGroup v-model:value="model.visible">
                <ARadio value="0">是</ARadio>
                <ARadio value="1">否</ARadio>
              </ARadioGroup>
            </AFormItem>
          </ACol>
          <ACol :lg="12" :xs="24">
            <AFormItem label="常量路由" name="constant">
              <ARadioGroup v-model:value="model.constant">
                <ARadio value="0">是</ARadio>
                <ARadio value="1">否</ARadio>
              </ARadioGroup>
            </AFormItem>
          </ACol>
          <ACol :lg="12" :xs="24">
            <AFormItem label="外链" name="href">
              <AInput v-model:value="model.href as string" placeholder="请输入外链" autocomplete="off" />
            </AFormItem>
          </ACol>
        </template>

        <ACol :lg="12" :xs="24">
          <AFormItem label="状态" name="status">
            <ARadioGroup v-model:value="model.status">
              <ARadio v-for="item in enableStatusOptions" :key="item.value" :value="item.value">
                {{ item.label }}
              </ARadio>
            </ARadioGroup>
          </AFormItem>
        </ACol>
        <ACol :lg="12" :xs="24">
          <AFormItem label="显示顺序" name="orderNum">
            <AInputNumber
              v-model:value="model.orderNum"
              placeholder="请输入显示顺序"
              class="w-full"
              autocomplete="off"
            />
          </AFormItem>
        </ACol>
        <ACol v-if="model.menuType != 'M'" :lg="12" :xs="24">
          <AFormItem label="权限字符" name="perms">
            <AInput v-model:value="model.perms" placeholder="请输入权限字符" autocomplete="off" />
          </AFormItem>
        </ACol>
        <ACol v-if="model.menuType == 'M' || model.menuType == 'C'" :lg="12" :xs="24">
          <AFormItem label="路径参数" name="pathParam">
            <AInput v-model:value="model.pathParam" placeholder="请输入路径参数" autocomplete="off" />
          </AFormItem>
        </ACol>
        <ACol v-if="model.menuType == 'M' || (model.menuType == 'C' && model.pathParam)" :lg="12" :xs="24">
          <AFormItem label="高亮的菜单" name="page">
            <ASelect
              v-model:value="model.activeMenu"
              :options="pageOptions"
              placeholder="请选择高亮的菜单"
              show-search
            />
          </AFormItem>
        </ACol>
        <ACol v-if="model.menuType == 'M' || model.menuType == 'C'" :span="24">
          <AFormItem :label-col="{ span: 4 }" label="路由参数" name="queryList">
            <AButton v-if="model.queryList.length === 0" type="dashed" block @click="addQuery(-1)">
              <template #icon>
                <icon-carbon-add class="align-sub text-icon" />
              </template>
              <span class="ml-8px">新增</span>
            </AButton>
            <template v-else>
              <div class="w-full">
                <div v-for="(item, index) in model.queryList" :key="index" class="flex gap-3">
                  <ACol :span="9">
                    <AFormItem :name="['queryList', index, 'key']">
                      <AInput
                        v-model:value="item.key"
                        placeholder="请输入路由参数key"
                        autocomplete="off"
                        class="flex-1"
                      />
                    </AFormItem>
                  </ACol>
                  <ACol :span="9">
                    <AFormItem :name="['queryList', index, 'value']">
                      <AInput
                        v-model:value="item.value"
                        placeholder="请输入路由参数value"
                        autocomplete="off"
                        class="flex-1"
                      />
                    </AFormItem>
                  </ACol>
                  <ACol :span="5">
                    <ASpace class="ml-12px">
                      <AButton size="middle" @click="addQuery(index)">
                        <template #icon>
                          <icon-ic:round-plus class="align-sub text-icon" />
                        </template>
                      </AButton>
                      <AButton size="middle" @click="removeQuery(index)">
                        <template #icon>
                          <icon-ic-round-remove class="align-sub text-icon" />
                        </template>
                      </AButton>
                    </ASpace>
                  </ACol>
                </div>
              </div>
            </template>
          </AFormItem>
        </ACol>
      </ARow>
    </AForm>
  </div>
</template>

<style></style>
